import java.util.*;

public class BitCalculate {
    static public List<Integer> generateKMArr(int K, int M, int Knum, int Mnum, int maxNum)
    {
        HashSet<Integer> already_marker = new HashSet<>();
        LinkedList<Integer> arr = new LinkedList<>();

        for(int i = 0;i<Knum;i++)
        {
            int num = (int)(maxNum*Math.random());
            while(already_marker.contains(num))
            {
                num=(int)(maxNum*Math.random());
            }
            already_marker.add(num);
            for(int j = 0;j<K;j++)
            {
                arr.add(num);
            }
        }

        for(int i = 0;i<Mnum;i++)
        {
            int num = (int)(maxNum*Math.random());
            while(already_marker.contains(num))
            {
                num=(int)(maxNum*Math.random());
            }
            already_marker.add(num);
            for(int j = 0;j<M;j++)
            {
                arr.add(num);
            }
        }

        Collections.shuffle(arr);

        return arr;
    }

    static public int randomEven(int min, int max)
    {
        if(max<=min) System.out.println("max<=min");
        int a = (int)(Math.random()*(max-min)+min);
        if(a%2==1) a+=1;
        return a;
    }

    static public int randomOdd(int min, int max)
    {
        if(max<=min) System.out.println("max<=min");
        int a = (int)(Math.random()*(max-min)+min);
        if(a%2==0) a+=1;
        return a;
    }

    static public void findParticularNumNumber(List<Integer> arr, int num)//找特定数量的数
    {
        int answer = 0;
        HashMap<Integer,Integer> counter = new HashMap<>();
        int len = arr.size();

        for (Integer temp : arr) {
            if (counter.containsKey(temp)) counter.put(temp, counter.get(temp) + 1);
            else {
                counter.put(temp, 1);
            }
        }

        Set<Integer> KeySet = counter.keySet();
        System.out.print("Hashmap Answer: ");
        for (Integer key: KeySet) if(counter.get(key)==num) System.out.print(" " + key);
    }

    static public void getOnlyOddNumNumber(List<Integer> arr)
    {
        int eor = 0;
        for(Integer temp : arr)
        {
            eor ^= temp;
        }
        System.out.println("EOR Answer: "+ eor);
    }

    static public void getOnlyTwoOddNumNumber(List<Integer> arr)
    {
        int eor = 0;
        for(Integer temp : arr)
        {
            eor ^= temp;
        }
        //eor = a^b

        int rightOne = eor&(-eor);

        int eor_ = 0;
        for(Integer temp : arr)
        {
            if((temp & rightOne) !=0) eor_^=temp;
        }

        System.out.println("Eor and Eor_ Answer: "+(eor_^eor) +" " +eor_);
    }

    static public void km(List<Integer> arr, int K, int M)
    {
        int[] bitCounter = new int[32];
        for(int i = 0; i<32; i++) bitCounter[i] = 0;

        for(Integer temp : arr)
        {
            for(int i = 0; i<32; i++)
            {
                if((temp>>i & 1) != 0) bitCounter[i]+=1;
            }
        }

        int ans = 0;
        for(int i = 0; i<32; i++)
        {
            if(bitCounter[i]%M!=0) ans^= 1<<i;
        }
        System.out.println("bit ans: "+ ans);
    }

    static public void main(String[] args)
    {
        System.out.println("============ only odd num number ===========");
        int K = randomOdd(3,10);
        int M = randomEven(3,10);

        List<Integer> arr = generateKMArr(K,M,1,(int)(10*Math.random()),100);
        for(Integer temp : arr)  System.out.print(temp+" ");
        System.out.println(" ");
        getOnlyOddNumNumber(arr);
        findParticularNumNumber(arr,K);

        System.out.println(" ");
        System.out.println(" ");
        System.out.println("============ only two odd num number ===========");

        K = randomOdd(3,10);
        M = randomEven(3,10);
        arr = generateKMArr(K,M,2,(int)(3+10*Math.random()),100);
        for(Integer temp : arr)  System.out.print(temp+" ");
        System.out.println(" ");
        getOnlyTwoOddNumNumber(arr);
        findParticularNumNumber(arr,K);

        System.out.println(" ");
        System.out.println(" ");
        System.out.println("============ KM number ===========");

        K = 1+(int)(10*Math.random());
        M = M+(int)(1+10*Math.random());
        arr = generateKMArr(K,M,1, (int)(1+10*Math.random()),100);
        km(arr,K,M);
        findParticularNumNumber(arr,K);


    }
}
